﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;

namespace WMI.NET.CIM
{
    /// <summary>
    /// The CIM_Printer class represents the capabilities and management of the printer logical device.
    /// </summary>
    public class CIM_Printer : CIM_LogicalDevice
    {

        private string[] _AvailableJobSheets;
        private UInt16[] _Capabilities;
        private string[] _CapabilityDescriptions;
        private string[] _CharSetsSupported;
        private UInt16[] _CurrentCapabilities;
        private string _CurrentCharSet;
        private Nullable<UInt16> _CurrentLanguage;
        private string _CurrentMimeType;
        private string _CurrentNaturalLanguage;
        private string _CurrentPaperType;
        private UInt16[] _DefaultCapabilities;
        private Nullable<UInt32> _DefaultCopies;
        private Nullable<UInt16> _DefaultLanguage;
        private string _DefaultMimeType;
        private Nullable<UInt32> _DefaultNumberUp;
        private string _DefaultPaperType;
        private Nullable<UInt16> _DetectedErrorState;
        private string[] _ErrorInformation;
        private Nullable<UInt32> _HorizontalResolution;
        private Nullable<UInt32> _JobCountSinceLastReset;
        private UInt16[] _LanguagesSupported;
        private Nullable<UInt16> _MarkingTechnology;
        private Nullable<UInt32> _MaxCopies;
        private Nullable<UInt32> _MaxNumberUp;
        private Nullable<UInt32> _MaxSizeSupported;
        private string[] _MimeTypesSupported;
        private string[] _NaturalLanguagesSupported;
        private UInt16[] _PaperSizesSupported;
        private string[] _PaperTypesAvailable;
        private Nullable<UInt16> _PrinterStatus;
        private Nullable<DateTimeOffset> _TimeOfLastReset;
        private Nullable<UInt32> _VerticalResolution;

        /// <summary>
        /// Describes all of the job sheets that are available on the printer. This can also be used to describe the banner that a printer might provide at the beginning of each job, or can describe other user specified options.
        /// </summary>
        public string[] AvailableJobSheets { get { return _AvailableJobSheets; } }

        /// <summary>
        /// Printer capabilities. 
        /// </summary>
        public UInt16[] Capabilities { get { return _Capabilities; } } //TODO enum

        /// <summary>
        /// Free-form strings that provide detailed explanations for any of the printer features indicated in the Capabilities array.
        /// Note  Each entry of this array is related to the entry in the Capabilities array that is located at the same index.
        /// </summary>
        public string[] CapabilityDescriptions { get { return _CapabilityDescriptions; } }

        /// <summary>
        /// Available character sets for the output of text related to managing the printer. Strings provided in this property should conform to the semantics and syntax specified by section 4.1.2 ("Charset parameter") in RFC 2046 (MIME Part 2), and contained in the IANA character-set registry. Examples include "utf-8", "us-ascii", and "iso-8859-1". This property was added for Windows XP and later.
        /// </summary>
        public string[] CharSetsSupported { get { return _CharSetsSupported; } }

        /// <summary>
        /// Finishings and other capabilities of the printer that are currently in use. Each entry in this property should also be listed in the Capabilities array.
        /// </summary>
        public UInt16[] CurrentCapabilities { get { return _CurrentCapabilities; } } //TODO enum

        /// <summary>
        /// Current character set used for the output of text relating to management of the printer. The character set described by this property should also be listed in the CharsetsSupported property. The string specified by this property should conform to the semantics and syntax specified by section 4.1.2 ("Charset parameter") in RFC 2046 (MIME Part 2), and contained in the IANA character-set registry. Examples include "utf-8", "us-ascii", and "iso-8859-1".
        /// </summary>
        public string CurrentCharSet { get { return _CurrentCharSet; } }

        /// <summary>
        /// Current printer language being used; the language should also be listed in the LanguagesSupported property.
        /// </summary>
        public Nullable<UInt16> CurrentLanguage { get { return _CurrentLanguage; } } //TOOD enum

        /// <summary>
        /// Mime type currently in use by the printer when the CurrentLanguage property is set to indicate that a mime type is in use.
        /// </summary>
        public string CurrentMimeType { get { return _CurrentMimeType; } }

        /// <summary>
        /// Current language in use by the printer for management. The language listed here should also be listed in NaturalLanguagesSupported.
        /// </summary>
        public string CurrentNaturalLanguage { get { return _CurrentNaturalLanguage; } }

        /// <summary>
        /// Paper type currently in use by the printer. The string should be expressed in the form specified by ISO/IEC 10175 Document Printing Application (DPA), which is also summarized in Appendix C of RFC 1759 (Printer MIB).
        /// </summary>
        public string CurrentPaperType { get { return _CurrentPaperType; } }

        /// <summary>
        /// Default finishings and other capabilities of the printer. Each entry in this property should also be listed in the Capabilities array.
        /// </summary>
        public UInt16[] DefaultCapabilities { get { return _DefaultCapabilities; } } //TODO enum

        /// <summary>
        /// Number of copies that a single job will produce, unless otherwise specified.
        /// </summary>
        public Nullable<UInt32> DefaultCopies { get { return _DefaultCopies; } }

        /// <summary>
        /// Default printer language. The language should also be listed in the LanguagesSupported property.
        /// </summary>
        public Nullable<UInt16> DefaultLanguage { get { return _DefaultLanguage; } } //TODO enum

        /// <summary>
        /// Default mime type used by the printer when the DefaultLanguage property is set to indicate that a mime type is in use.
        /// </summary>
        public string DefaultMimeType { get { return _DefaultMimeType; } }

        /// <summary>
        /// Number of print-stream pages that the printer will render onto a single media sheet, unless a job specifies otherwise.
        /// </summary>
        public Nullable<UInt32> DefaultNumberUp { get { return _DefaultNumberUp; } }

        /// <summary>
        /// Paper type that the printer will use if PrintJob does not specify a particular type. The string should be expressed in the form specified by ISO/IEC 10175 Document Printing Application (DPA), which is also summarized in Appendix C of RFC 1759 (Printer MIB).
        /// </summary>
        public string DefaultPaperType { get { return _DefaultPaperType; } }

        /// <summary>
        /// Printer error information.
        /// </summary>
        public Nullable<UInt16> DetectedErrorState { get { return _DetectedErrorState; } }

        /// <summary>
        /// Array that provides supplemental information for the current error state, indicated in the DetectedErrorState property.
        /// </summary>
        public string[] ErrorInformation { get { return _ErrorInformation; } set { throw new NotImplementedException(); } } //TODO set

        /// <summary>
        /// Horizontal resolution in pixels-per-inch.
        /// </summary>
        public Nullable<UInt32> HorizontalResolution { get { return _HorizontalResolution; } }

        /// <summary>
        /// Printer jobs processed since the last reset. These jobs can be processed from one or more print queues.
        /// </summary>
        public Nullable<UInt32> JobCountSinceLastReset { get { return _JobCountSinceLastReset; } }

        /// <summary>
        /// Print languages that are natively supported.
        /// </summary>
        public UInt16[] LanguagesSupported { get { return _LanguagesSupported; } } //TODO enum

        /// <summary>
        /// Marking technology used by the printer.
        /// </summary>
        public Nullable<UInt16> MarkingTechnology { get { return _MarkingTechnology; } } //TODO enum

        /// <summary>
        /// Maximum number of copies that can be produced by the printer from a single job.
        /// </summary>
        public Nullable<UInt32> MaxCopies { get { return _MaxCopies; } }

        /// <summary>
        /// Maximum number of print-stream pages that the printer can render onto a single media sheet.
        /// </summary>
        public Nullable<UInt32> MaxNumberUp { get { return _MaxNumberUp; } }

        /// <summary>
        /// Largest job (as a byte stream) that the printer will accept in units of kilobytes. A value of 0 (zero) indicates that no limit has been set.
        /// </summary>
        public Nullable<UInt32> MaxSizeSupported { get { return _MaxSizeSupported; } }

        /// <summary>
        /// Free-form strings that provide detailed explanations of mime types that are supported by the printer. If data is provided for this property, then the value 47 ("Mime"), should be included in the LanguagesSupported property.
        /// </summary>
        public string[] MimeTypesSupported { get { return _MimeTypesSupported; } }

        /// <summary>
        /// Available languages for strings used by the printer for management information output. The strings should conform to RFC 1766. For example, "en" is used for English.
        /// </summary>
        public string[] NaturalLanguagesSupported { get { return _NaturalLanguagesSupported; } }

        /// <summary>
        /// Types of paper supported.
        /// </summary>
        public UInt16[] PaperSizesSupported { get { return _PaperSizesSupported; } } //TODO enum

        /// <summary>
        /// Free-form strings that specify the types of paper that are currently available for the printer. Each string should be expressed in the form specified by ISO/IEC 10175 Document Printing Application (DPA), which is also summarized in Appendix C of RFC 1759 (Printer MIB). Examples of valid strings are "iso-a4-colored" and "na-10x14-envelope". By definition, a paper size that is available and listed in the PaperTypesAvailable property should also appear in the PaperSizesSupported property.
        /// </summary>
        public string[] PaperTypesAvailable { get { return _PaperTypesAvailable; } }

        /// <summary>
        /// Status information, beyond that specified in the Availability property, for a printer.
        /// </summary>
        public Nullable<UInt16> PrinterStatus { get { return _PrinterStatus; } } //TODO enum

        /// <summary>
        /// Time of last printer reset.
        /// </summary>
        public Nullable<DateTimeOffset> TimeOfLastReset { get { return _TimeOfLastReset; } }

        /// <summary>
        /// Vertical resolution in pixels-per-inch.
        /// </summary>
        public Nullable<UInt32> VerticalResolution { get { return _VerticalResolution; } }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="mbo"></param>
        public CIM_Printer(ManagementBaseObject mbo)
            : base(mbo)
        {
            _AvailableJobSheets = mbo.GetStringValueArray("AvailableJobSheets");
            _Capabilities = mbo.GetUshortValueArray("Capabilities");
            _CapabilityDescriptions = mbo.GetStringValueArray("CapabilityDescriptions");
            _CharSetsSupported = mbo.GetStringValueArray("CharSetsSupported");
            _CurrentCapabilities = mbo.GetUshortValueArray("CurrentCapabilities");
            _CurrentCharSet = mbo.GetStringValue("CurrentCharSet");
            _CurrentLanguage = mbo.GetUshortValue("CurrentLanguage");
            _CurrentMimeType = mbo.GetStringValue("CurrentMimeType");
            _CurrentNaturalLanguage = mbo.GetStringValue("CurrentNaturalLanguage");
            _CurrentPaperType = mbo.GetStringValue("CurrentPaperType");
            _DefaultCapabilities = mbo.GetUshortValueArray("DefaultCapabilities");
            _DefaultCopies = mbo.GetUIntValue("DefaultCopies");
            _DefaultLanguage = mbo.GetUshortValue("DefaultLanguage");
            _DefaultMimeType = mbo.GetStringValue("DefaultMimeType");
            _DefaultNumberUp = mbo.GetUIntValue("DefaultNumberUp");
            _DefaultPaperType = mbo.GetStringValue("DefaultPaperType");
            _DetectedErrorState = mbo.GetUshortValue("DetectedErrorState");
            _ErrorInformation = mbo.GetStringValueArray("ErrorInformation");
            _HorizontalResolution = mbo.GetUIntValue("HorizontalResolution");
            _JobCountSinceLastReset = mbo.GetUIntValue("JobCountSinceLastReset");
            _LanguagesSupported = mbo.GetUshortValueArray("LanguagesSupported");
            _MarkingTechnology = mbo.GetUshortValue("MarkingTechnology");
            _MaxCopies = mbo.GetUIntValue("MaxCopies");
            _MaxNumberUp = mbo.GetUIntValue("MaxNumberUp");
            _MaxSizeSupported = mbo.GetUIntValue("MaxSizeSupported");
            _MimeTypesSupported = mbo.GetStringValueArray("MimeTypesSupported");
            _NaturalLanguagesSupported = mbo.GetStringValueArray("NaturalLanguagesSupported");
            _PaperSizesSupported = mbo.GetUshortValueArray("PaperSizesSupported");
            _PaperTypesAvailable = mbo.GetStringValueArray("PaperTypesAvailable");
            _PrinterStatus = mbo.GetUshortValue("PrinterStatus");
            _TimeOfLastReset = mbo.GetDateTimeOffsetValue("TimeOfLastReset", Consts.DateTimeFormat);
            _VerticalResolution = mbo.GetUIntValue("VerticalResolution");
        }

    }
}
